package immutableObject;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: linKe
 * @Date: 2022/1/15 11:25
 * @FileName: MMSCRouter
 * @version: 1.0
 * @Description: 短信中心路由表
 * immutable Object不可变对象模式
 * 多线程共享变量的情况下，为了保证数据一致性，往往需要对这些变量的访问进行加锁。
 * 而锁本身又会带来一些问题和开销。
 * Immutable Object模式使得我们可以在不使用锁的情况下，既保证共享变量访问的线程安全，
 * 又能避免引入锁可能带来的问题和开销。
 *
 *
 *  获取单个状态的值：调用不可变对象的相关getter方法即可实现。
 *  获取一组状态的快照：不可变对象可以提供一个getter方法，该方法需要对其返回值做防御性拷贝或者返回一个只读的对象，以避免其状态对外泄露而被改变。
 *  生成新的不可变对象实例：当被建模对象的状态发生变化的时候，创建新的不可变对象实例来反映这种变化。
 */
public class MMSCRouter {
    private static volatile MMSCRouter instance = new MMSCRouter();
    /**
     * 维护手机号前缀和短信中心的关系
     */
    private final Map<String, MMSCInfo> routerMap;

    public MMSCRouter() {
        this.routerMap = retrieveRouteMapFromDB();
    }

    /**
     * 从数据库读取映射关系，再次只是模拟实现
     * @return 路由表
     */
    private Map<String, MMSCInfo> retrieveRouteMapFromDB() {
        return new HashMap<String, MMSCInfo>(10);
    }

    /**
     * 整个替换路由表
     * @param newInstance 新实例对象
     */
    public static void setInstance(MMSCRouter newInstance) {
        instance = newInstance;
    }

    public static MMSCRouter getInstance() {
        return instance;
    }

    /**
     * 根据手机号前缀查找短信中心
     * @param msisdnPrefix 手机号前缀
     * @return 短信中心
     */
    public MMSCInfo getMMSC(String msisdnPrefix) {
        return routerMap.get(msisdnPrefix);
    }

    /**
     * 获取路由集合
     * @return  结果
     */
    public Map<String, MMSCInfo> getRouterMap() {
        return Collections.unmodifiableMap(routerMap);
    }

}
